package com.evan.review.ipc;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.Process;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.evan.review.R;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 管道和消息队列通信示例
 * 演示如何使用管道和消息队列进行线程间通信
 * 注意：这些机制主要用于线程间通信，而非进程间通信
 */
public class PipeAndMessageQueueActivity extends AppCompatActivity {

    private static final String TAG = "PipeAndMsgQueueDemo";
    private static final int MSG_RECEIVED_DATA = 1;
    private static final int MSG_PIPE_ERROR = 2;
    
    private TextView tvStatus;
    private TextView tvReceivedData;
    private EditText etMessage;
    private Button btnSendPipe;
    private Button btnSendMessage;
    private Button btnClearLog;
    private Button btnShowInfo;
    
    // 线程池
    private final ExecutorService executor = Executors.newFixedThreadPool(2);
    
    // 管道流
    private PipedOutputStream pipeOut;
    private PipedInputStream pipeIn;
    
    // 消息处理
    private Handler mainHandler;
    private WorkerHandler workerHandler;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pipe_message_queue);
        
        // 初始化视图
        initViews();
        // 初始化管道
        initPipe();
        // 初始化消息处理
        initMessageHandling();
        // 设置点击监听
        setupListeners();
        
        // 显示当前进程ID
        appendStatus("当前进程ID: " + Process.myPid());
    }
    
    private void initViews() {
        tvStatus = findViewById(R.id.tv_pipe_status);
        tvReceivedData = findViewById(R.id.tv_received_data);
        etMessage = findViewById(R.id.et_pipe_message);
        btnSendPipe = findViewById(R.id.btn_send_pipe);
        btnSendMessage = findViewById(R.id.btn_send_message);
        btnClearLog = findViewById(R.id.btn_clear_log);
        btnShowInfo = findViewById(R.id.btn_pipe_info);
    }
    
    private void initPipe() {
        try {
            pipeOut = new PipedOutputStream();
            pipeIn = new PipedInputStream(pipeOut);
            
            // 启动读取线程
            executor.execute(new PipeReaderTask());
            appendStatus("管道初始化成功");
        } catch (IOException e) {
            Log.e(TAG, "管道初始化失败: " + e.getMessage());
            appendStatus("管道初始化失败: " + e.getMessage());
            btnSendPipe.setEnabled(false);
        }
    }
    
    private void initMessageHandling() {
        // 主线程Handler
        mainHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    case MSG_RECEIVED_DATA:
                        String data = (String) msg.obj;
                        appendReceivedData("消息队列: " + data);
                        break;
                    case MSG_PIPE_ERROR:
                        String error = (String) msg.obj;
                        appendStatus("管道错误: " + error);
                        break;
                }
            }
        };
        
        // 启动工作线程
        new Thread(() -> {
            Looper.prepare();
            workerHandler = new WorkerHandler(Looper.myLooper());
            Looper.loop();
        }, "Worker-Thread").start();
        
        // 等待工作线程Handler初始化
        while (workerHandler == null) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        appendStatus("消息处理初始化成功");
    }
    
    private void setupListeners() {
        // 通过管道发送数据
        btnSendPipe.setOnClickListener(v -> sendThroughPipe());
        
        // 通过消息队列发送数据
        btnSendMessage.setOnClickListener(v -> sendThroughMessageQueue());
        
        // 清空日志
        btnClearLog.setOnClickListener(v -> {
            tvReceivedData.setText("");
            tvStatus.setText("");
            appendStatus("日志已清空");
        });
        
        // 显示信息介绍
        btnShowInfo.setOnClickListener(v -> showPipeAndMessageQueueInfo());
    }
    
    /**
     * 通过管道发送数据
     */
    private void sendThroughPipe() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        executor.execute(() -> {
            try {
                // 添加时间戳
                String timestamp = new SimpleDateFormat("HH:mm:ss", Locale.getDefault())
                        .format(new Date());
                String dataToSend = timestamp + " - " + message + "\n";
                
                // 写入管道
                pipeOut.write(dataToSend.getBytes(StandardCharsets.UTF_8));
                pipeOut.flush();
                
                runOnUiThread(() -> {
                    appendStatus("数据已通过管道发送: " + message);
                    etMessage.setText("");
                });
            } catch (IOException e) {
                Log.e(TAG, "管道写入错误: " + e.getMessage());
                runOnUiThread(() -> 
                    appendStatus("管道写入错误: " + e.getMessage())
                );
            }
        });
    }
    
    /**
     * 通过消息队列发送数据
     */
    private void sendThroughMessageQueue() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        // 添加时间戳
        String timestamp = new SimpleDateFormat("HH:mm:ss", Locale.getDefault())
                .format(new Date());
        String dataToSend = timestamp + " - " + message;
        
        // 发送消息到工作线程
        Message msg = Message.obtain();
        msg.what = MSG_RECEIVED_DATA;
        msg.obj = dataToSend;
        workerHandler.sendMessage(msg);
        
        appendStatus("数据已通过消息队列发送: " + message);
        etMessage.setText("");
    }
    
    /**
     * 管道读取任务
     */
    private class PipeReaderTask implements Runnable {
        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytesRead;
            
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    bytesRead = pipeIn.read(buffer);
                    if (bytesRead > 0) {
                        final String receivedData = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8);
                        runOnUiThread(() -> 
                            appendReceivedData("管道: " + receivedData.trim())
                        );
                    }
                }
            } catch (IOException e) {
                if (!Thread.currentThread().isInterrupted()) {
                    Log.e(TAG, "管道读取错误: " + e.getMessage());
                    Message msg = Message.obtain();
                    msg.what = MSG_PIPE_ERROR;
                    msg.obj = e.getMessage();
                    mainHandler.sendMessage(msg);
                }
            }
        }
    }
    
    /**
     * 工作线程Handler
     */
    private class WorkerHandler extends Handler {
        public WorkerHandler(Looper looper) {
            super(looper);
        }
        
        @Override
        public void handleMessage(@NonNull Message msg) {
            // 工作线程处理消息
            if (msg.what == MSG_RECEIVED_DATA) {
                String data = (String) msg.obj;
                
                // 模拟处理数据
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                // 处理完成后发送回主线程
                Message responseMsg = Message.obtain();
                responseMsg.what = MSG_RECEIVED_DATA;
                responseMsg.obj = data + " (已处理)";
                mainHandler.sendMessage(responseMsg);
            }
        }
    }
    
    /**
     * 显示管道和消息队列介绍对话框
     */
    private void showPipeAndMessageQueueInfo() {
        new androidx.appcompat.app.AlertDialog.Builder(this)
                .setTitle("管道和消息队列介绍")
                .setMessage("管道和消息队列是两种常见的线程间通信机制。\n\n" +
                        "管道 (Pipe)：\n" +
                        "- 基于流的数据传输方式\n" +
                        "- 单向通信，需要一对输入/输出流\n" +
                        "- 适用于二进制数据传输\n" +
                        "- Java中使用PipedInputStream/PipedOutputStream实现\n" +
                        "- 主要用于线程间通信，而非进程间\n\n" +
                        "消息队列 (MessageQueue)：\n" +
                        "- Android消息机制的核心组件之一\n" +
                        "- 与Handler和Looper配合使用\n" +
                        "- 可传递复杂数据结构\n" +
                        "- 支持延时消息和优先级\n" +
                        "- 主要用于线程间通信\n\n" +
                        "进程间通信应用：\n" +
                        "- 管道：Linux中可用于进程间通信，但Java中主要用于线程间\n" +
                        "- 消息队列：Android中Handler机制主要用于线程间，Binder和Messenger才是进程间")
                .setPositiveButton("了解", null)
                .show();
    }
    
    /**
     * 获取输入的消息文本
     */
    private String getMessageText() {
        String message = etMessage.getText().toString().trim();
        if (message.isEmpty()) {
            message = "测试消息 " + System.currentTimeMillis();
            Toast.makeText(this, "使用默认消息", Toast.LENGTH_SHORT).show();
        }
        return message;
    }
    
    /**
     * 添加状态信息
     */
    private void appendStatus(String status) {
        String currentText = tvStatus.getText().toString();
        tvStatus.setText((currentText.isEmpty() ? "" : currentText + "\n") + status);
    }
    
    /**
     * 添加接收到的数据
     */
    private void appendReceivedData(String data) {
        String currentText = tvReceivedData.getText().toString();
        tvReceivedData.setText((currentText.isEmpty() ? "" : currentText + "\n") + data);
    }
    
    @Override
    protected void onDestroy() {
        // 关闭管道
        try {
            if (pipeIn != null) pipeIn.close();
            if (pipeOut != null) pipeOut.close();
        } catch (IOException e) {
            Log.e(TAG, "关闭管道错误: " + e.getMessage());
        }
        
        // 关闭工作线程Looper
        if (workerHandler != null && workerHandler.getLooper() != null) {
            workerHandler.getLooper().quit();
        }
        
        // 关闭线程池
        executor.shutdownNow();
        
        super.onDestroy();
    }
} 